#pragma once
#include <string>
#include <websocketpp/server.hpp>
#include <websocketpp/config/asio_no_tls.hpp>
#include <unordered_map>
#include <mutex>

typedef websocketpp::server<websocketpp::config::asio> WsServer_t;

class Online_Manager
{
public:
    Online_Manager()
    {
    }
    ~Online_Manager()
    {
    }

public:
    // websocket连接建立时才会进入游戏大厅
    bool Enter_game_hall(int uid, WsServer_t::connection_ptr &conn)
    {
        {
            std::lock_guard<std::mutex> lock(_mutex);
            _hall_conns[uid] = conn;
        }
        return true;
    }
    // websocket连接断开时才会进入游戏大厅
    bool Exit_game_hall(int uid)
    {
        {
            std::lock_guard<std::mutex> lock(_mutex);
            _hall_conns.erase(uid);
        }
        return true;
    }
    bool Enter_game_room(int uid, WsServer_t::connection_ptr &conn)
    {
        {
            std::lock_guard<std::mutex> lock(_mutex);
            _gameroom_conns[uid] = conn;
        }
        return true;
    }
    bool Exit_game_room(int uid)
    {
        {
            std::lock_guard<std::mutex> lock(_mutex);
            _gameroom_conns.erase(uid);
        }
        return true;
    }

    // 用户是否在游戏房间内
    bool is_in_game_room(int uid)
    {
        {
            std::lock_guard<std::mutex> lock(_mutex);
            auto it = _gameroom_conns.find(uid);
            if (it == _gameroom_conns.end()) // 该用户不在游戏房间内
            {
                return false;
            }
        }
        return true;
    }
    // 用户是否在游戏大厅内
    bool is_in_game_hall(int uid)
    {
        {
            std::lock_guard<std::mutex> lock(_mutex);
            auto it = _hall_conns.find(uid);
            if (it == _hall_conns.end()) // 该用户不在游戏大厅内
            {
                return false;
            }
        }
        return true;
    }

    // 通过用户id获取处于游戏大厅中的该用户的websocket连接
    WsServer_t::connection_ptr get_conn_from_hall(int uid)
    {
        if (is_in_game_hall(uid))
        {
            return _hall_conns[uid];
        }
        return NULL;
    }

    // 通过用户id获取处于游戏房间中的该用户的websocket连接
    WsServer_t ::connection_ptr get_conn_from_room(int uid)
    {
        if (is_in_game_room(uid))
        {
            return _gameroom_conns[uid];
        }
        return NULL;
    }

private:
    // < id , 指向websocket长连接对象的指针 >
    // 1.管理处于游戏大厅的用户的websocket长连接
    std::unordered_map<int, WsServer_t::connection_ptr> _hall_conns;
    // 2.管理处于游戏房间的用户的websocket长连接
    std::unordered_map<int, WsServer_t::connection_ptr> _gameroom_conns;

    //_hall_conns和_gameroom_conns在多线程下都是共享资源,需要加锁
    std::mutex _mutex;
};
